local clsaver = LibStub("AceAddon-3.0"):NewAddon(
  "clsaver", "AceEvent-3.0", "AceConsole-3.0")

function clsaver:OnInitialize()
  local defaults = {
    profile = {
      zone_overrides = {},
    }
  }
  self.db = LibStub("AceDB-3.0"):New("clsaver_DB", defaults, true)
  self.version = GetAddOnMetadata("clsaver", "Version")
  self:RegisterChatCommand("clsaver", "ProcessCommand")
end

function clsaver:PrintHelp()
  local help = {
    "CombatLog Saver - "..self.version,
    "   CombatLog logging is on when you are inside a raid instance, unless there is an override",
    "   list - Lists zones that have an override",
    "   override <on/off/none> - Sets an override for the current zone. none reverts to default which is logging when inside a raid instance",
  }
  self:Print(table.concat(help, "\n"))
end

function clsaver:ProcessCommand(str)
  local command, nextposition = self:GetArgs(str, 1)
  if command == "list" then
    self:ListZoneOverrides()
  elseif command == "override" then
    local arg = self:GetArgs(str, 1, nextposition)
    if arg == "on" then
      arg = true
    elseif arg == "off" then
      arg = false
    elseif arg == "none" then
      arg = nil
    else
      self:PrintHelp()
      return
    end
    self.db.profile.zone_overrides[GetRealZoneText()] = arg
    self:OnZoneChanged()
  else
    self:PrintHelp()
  end
end

function clsaver:OnEnable()
  self:RegisterEvent("ZONE_CHANGED_NEW_AREA", "OnZoneChanged")
  self:RegisterEvent("PLAYER_ENTERING_WORLD", "OnZoneChanged")
end

function clsaver:IsInRaidInstance()
  local inInstance, instanceType = IsInInstance()
  if not inInstance then
    return false
  end
  if not (instanceType == "party" or instanceType == "raid") then
    return false
  end
  return UnitInRaid("player")
end

function clsaver:IsZoneTracked()
  local override = self.db.profile.zone_overrides[GetRealZoneText()]
  if override ~= nil then
    return override
  else
    return self:IsInRaidInstance()
  end
end

function clsaver:ListZoneOverrides()
  if next(self.db.profile.zone_overrides) then
    self:Print("Zone overrides:")
    for z,s in pairs(self.db.profile.zone_overrides) do
      self:Print(string.format("* %s %s", z, s and "on" or "off"))
    end
  else
    self:Print("No zone overrides.")
  end
end

function clsaver:StartLogging()
  assert(not LoggingCombat())
  UIErrorsFrame:AddMessage("CombatLog ON", 0.2, 1.0, 0.2, 1.0,
                           UIERRORS_HOLD_TIME)
  LoggingCombat(true)
end

function clsaver:StopLogging()
  assert(LoggingCombat())
  UIErrorsFrame:AddMessage("CombatLog OFF", 1.0, 0.0, 0.0, 1.0,
                           UIERRORS_HOLD_TIME)
  LoggingCombat(false)
end

function clsaver:OnZoneChanged()
  if (self:IsZoneTracked() and not LoggingCombat()) then
    self:StartLogging()
  elseif (not self:IsZoneTracked() and LoggingCombat()) then
    self:StopLogging()
  end
end
